﻿using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.Practices.Unity;

namespace RG.Common
{
    /// <summary>
    /// Базовый класс для WCF-прокси на стороне клиента.
    /// Создаёт FactoryWrapper при первом вызове метода интерфейса
    /// </summary>
    public abstract class AbstractServiceBase<TChannel>
        where TChannel : class
    {
        private FactoryWrapperBase<TChannel> fw;
        protected FactoryWrapperBase<TChannel> Factory
        {
            get
            {
                if (fw == null)
                {
                    fw = CreateFactoryWarapper();
                    fw.OnSpecificHeaders = AddSpecificHeaders;
                }
                return fw;
            }
        }

        private FactoryWrapperBase<TChannel> CreateFactoryWarapper()
        {
            var endpoint = GetEndpointAddress();
            return endpoint == null
                       ? new FactoryWrapperBase<TChannel>(GetEndpointName())
                       : new FactoryWrapperBase<TChannel>(GetBinding(), endpoint);
        }

        /// <summary>
        /// Принудительно требуется переопределение, чтобы не забыли
        /// </summary>
        protected abstract void AddSpecificHeaders(EndpointAddressBuilder builder);
        
        protected virtual Binding GetBinding()
        {
            return null;
        }

        protected virtual string GetEndpointName()
        {
            return null;
        }

        protected virtual EndpointAddress GetEndpointAddress()
        {
            return null;
        }
    }

    /// <summary>
    /// Базовый класс для WCF-прокси на стороне клиента.
    /// Умеет автоматически конструировать endpoint name 
    /// по принципу <Конфигурация>.<Интерфейс-без-начальной-I>.
    /// </summary>
    public abstract class ServiceBase<TChannel> : AbstractServiceBase<TChannel>
        where TChannel : class
    {
        [Dependency("ServicesPrefix")]
        public string Prefix { get; set; }

        protected override string GetEndpointName()
        {
            string ifname = typeof(TChannel).Name;
            if (ifname != "" && ifname[0] == 'I')
                ifname = ifname.Substring(1);
            return Prefix + "." + ifname;
        }
    }

  
}
